/**
 * 通过 new Proxy 来给 dong 定义了 get、set、ownKeys 的 handler：

get: 如果以下划线 _ 开头就返回空，否则返回目标对象的属性值 target[prop]。

set: 如果以下划线 _ 开头就直接返回，否则设置目标对象的属性值。

ownKeys: 访问 keys 时，过滤掉目标对象中下划线开头的属性再返回。

这样就实现了下划线开头的属性的私有化：
 * @param {*} obj 
 * @returns 
 */
function getProxyObj(obj) {
  return new Proxy(obj, {
    // 获取_开头的返回空
    get(target, key) {
      if (key.startsWith("_")) return "";
      return target[key];
    },

    set(target, prop, value) {
      if (prop.startsWith("_")) {
        return;
      }
      target[prop] = value;
    },
    // ownKes能拦截 Object.keys(),Object.getOwnPropertyNames(),Object.getOwnPropertySymbols(),Reflect.ownKeys()
    // ownKeys 的结果必须是一个数组。 数组的元素类型要么是一个 String ，要么是一个 Symbol.
    ownKeys(target) {
      return Reflect.ownKeys(target).filter((item) => !item.startsWith("_"));
    },
  });
}

let obj = {
  a: 1,
  _b: 2,
  c: 3,
};

let pObj = getProxyObj(obj);

console.log("[ pObj ] >", pObj["_b"]);
console.log("[ pObj ] >", Object.keys(pObj));
console.log("[ pObj ] >", Object.keys(obj));
